using System;
using System.Linq;
using DNT.RavenQA.Core.Extensions;
using DNT.RavenQA.Core.Models;
using DNT.RavenQA.Web.Infrastructure.Extensions;
using Raven.Abstractions.Data;
using Raven.Client.Indexes;
using Raven.Json.Linq;

namespace DNT.RavenQA.Web.Infrastructure.Indexing
{
    public class ContributesByAuthorIdIndex : AbstractMultiMapIndexCreationTask<ContributesByAuthorIdIndex.ReduceResult>
    {
        public class ReduceResult
        {
            public String UserId { get; protected set; }
        }

        public const String INDEX_NAME = "ContributesByAuthorId";

        public override String IndexName
        {
            get { return INDEX_NAME; }
        }

        public static PatchRequest BuildContributesPatchRequest(String userName)
        {
            userName.EnsureIsNotNullOrEmpty("userName");

            return new PatchRequest
                       {
                           Type = PatchCommandType.Modify,
                           Name = Name.Of<Contribute>(c => c.User),
                           Nested = new[]
                                        {
                                            new PatchRequest
                                                {
                                                    Type = PatchCommandType.Set,
                                                    Name = Name.Of<INamedDocument>(n => n.Name),
                                                    Value = RavenJToken.FromObject(userName)
                                                }
                                        }
                       };
        }

        public static IndexQuery BuildQueryContributesByUserId(String userId)
        {
            userId.EnsureIsNotNullOrEmpty("userId");

            return new IndexQuery
                       {
                           Query = String.Format("{0}:{1}",
                                                 Name.Of<ReduceResult>(i => i.UserId),
                                                 userId)
                       };
        }

        public ContributesByAuthorIdIndex()
        {
            AddMap<Question>(questions => questions.Select(c => new { UserId = c.User.Id}));
            AddMap<Answer>(answers => answers.Select(d => new { UserId = d.User.Id}));
        }
    }
}